﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Sworm;

namespace SwormTests.Joins
{
    public class simple_one_to_many : TestBase
    {
        public simple_one_to_many(DbToTest type) : base(type) { }

        class parent
        {
            [Sworm.Column(IsPrimaryKey = true, IsAutoIncrement = false)]
            public long id { get; set; }
            public string name { get; set; }
            public List<child> Children { get; set; }
        }

        class child
        {
            [Sworm.Column(IsPrimaryKey = true, IsAutoIncrement = false)]
            public long id { get; set; }
            public string name { get; set; }
            public long owner_id { get; set; }
            public parent Owner { get; set; }
        }

        [Test]
        public void child_join_null_owner()
        {
            var first = new child() { id = 53, name = "the name" };
            DB.Insert(first);

            var children = DB.Query.Joining<child>("c")
                .JoinLeft(c => c.Owner, "owner")
                .List();

            Assert.AreEqual(1, children.Count);
            first = children.Single();
            Assert.AreEqual(53, first.id);
            Assert.AreEqual("the name", first.name);
            Assert.IsNull(first.Owner);
        }

        [Test]
        public void children_join_shared_owner()
        {
            var parent = new parent() { id = 33, name = "parent" };
            var child1 = new child() { id = 11, name = "one", owner_id = parent.id };
            var child2 = new child() { id = 22, name = "two", owner_id = parent.id };

            DB.Insert(parent);
            DB.Insert(child1);
            DB.Insert(child2);

            var children = DB.Query.Joining<child>("c")
                .JoinLeft(c => c.Owner, "owner")
                .List();

            Assert.AreEqual(2, children.Count);
            child1 = children[0];
            child2 = children[1];
            Assert.IsNotNull(child1.Owner);
            Assert.AreSame(child1.Owner, child2.Owner);

            var owner = child1.Owner;
            Assert.AreEqual("parent", owner.name);
            Assert.AreEqual(33, owner.id);

            Assert.IsNotNull(owner.Children);
            Assert.AreEqual(2, owner.Children.Count);
            Assert.IsTrue(owner.Children.Contains(child1));
            Assert.IsTrue(owner.Children.Contains(child2));
        }

        [Test]
        public void owner_join_children()
        {
            var parent = new parent() { id = 33, name = "parent" };
            var child1 = new child() { id = 11, name = "one", owner_id = parent.id };
            var child2 = new child() { id = 22, name = "two", owner_id = parent.id };

            DB.Insert(parent);
            DB.Insert(child1);
            DB.Insert(child2);

            parent = DB.Query.Joining<parent>("p")
                .JoinLeft(p => p.Children, "c")
                .List()
                .Single();

            Assert.AreEqual(33, parent.id);
            Assert.AreEqual(2, parent.Children.Count);

            child1 = parent.Children.Single(c => c.id == child1.id);
            child2 = parent.Children.Single(c => c.id == child2.id);

            Assert.AreEqual("one", child1.name);
            Assert.AreEqual("two", child2.name);

            Assert.AreSame(parent, child1.Owner);
            Assert.AreSame(parent, child2.Owner);
        }
    }
}
